package info.batcloud.fanli.api.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.taobao.api.ApiException;
import com.taobao.api.TaobaoClient;
import com.taobao.api.request.TopAuthTokenCreateRequest;
import com.taobao.api.response.TopAuthTokenCreateResponse;
import info.batcloud.fanli.core.constants.TaobaoClientConstants;
import info.batcloud.fanli.core.constants.TopAuthConstants;
import info.batcloud.fanli.core.domain.BusinessResponse;
import info.batcloud.fanli.core.enums.CacheKeys;
import info.batcloud.fanli.core.helper.SecurityHelper;
import info.batcloud.fanli.core.service.*;
import info.batcloud.fanli.core.settings.TaobaoAuthSetting;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.inject.Inject;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Controller
@RequestMapping("/top")
public class TopController {

    @Inject
    @Qualifier(TaobaoClientConstants.TAOBAO_CLIENT_ITEM_TBK)
    private TaobaoClient tbkTaobaoClient;

    @Inject
    private TopService topService;

    @Inject
    private SystemSettingService systemSettingService;

    @Inject
    private TbkPrivateService tbkPrivateService;

    @Inject
    private RedisTemplate<String, String> redisTemplate;

    @Inject
    private TaobaoAccountService taobaoAccountService;

    @Inject
    private UserService userService;


    @GetMapping("/auth/url")
    @ResponseBody
    @PreAuthorize("hasRole('USER')")
    public Object authUrl() {
        Map<String, String> rs = new HashMap<>(1);
        String random = RandomStringUtils.random(10, true, true);
        redisTemplate.opsForValue().set(CacheKeys.TOP_USER_STATE + "-" + random, SecurityHelper.loginUserId().toString());
        rs.put("authUrl", topService.generateAuthUrl(TopAuthConstants.STATE_USER + ":" + random, "wap"));
        return BusinessResponse.ok(rs);
    }

    @GetMapping("/auth/callback")
    public String callback(String code, String state, ModelMap map) throws ApiException {

        TopAuthTokenCreateRequest request = new TopAuthTokenCreateRequest();
        request.setCode(code);
        TopAuthTokenCreateResponse res = tbkTaobaoClient.execute(request);
        if (!res.isSuccess()) {
            if (state.startsWith(TopAuthConstants.STATE_SYSTEM)) {
                return "close";
            } else {
                map.put("authOk", false);
                return "topAuth";
            }
        }
        JSONObject jsonObject = JSON.parseObject(res.getTokenResult());
        String accessToken = jsonObject.getString("access_token");
        long timestamp = System.currentTimeMillis();
        Date w1ExpiresIn = new Date(timestamp + jsonObject.getIntValue("w1_expires_in") * 1000);
        Date w2ExpiresIn = new Date(timestamp + jsonObject.getIntValue("w2_expires_in") * 1000);
        Date r1ExpiresIn = new Date(timestamp + jsonObject.getIntValue("r1_expires_in") * 1000);
        Date r2ExpiresIn = new Date(timestamp + jsonObject.getIntValue("r2_expires_in") * 1000);
        Date expiresIn = new Date(System.currentTimeMillis() + jsonObject.getLong("expires_in") * 1000);
        String refreshToken = jsonObject.getString("refresh_token");
        Long taobaoUserId = jsonObject.getLong("taobao_user_id");
        String taobaoUserNick = jsonObject.getString("taobao_user_nick");
        String taobaoOpenId = jsonObject.getString("taobao_open_id");
        String tokenType = jsonObject.getString("token_type");
        if (state.startsWith(TopAuthConstants.STATE_SYSTEM)) {
            TaobaoAuthSetting tbAuthSetting = systemSettingService.findActiveSetting(TaobaoAuthSetting.class);
            tbAuthSetting.setAccessToken(accessToken);
            tbAuthSetting.setW1ExpiresIn(w1ExpiresIn);
            tbAuthSetting.setW2ExpiresIn(w2ExpiresIn);
            tbAuthSetting.setR1ExpiresIn(r1ExpiresIn);
            tbAuthSetting.setR2ExpiresIn(r2ExpiresIn);
            tbAuthSetting.setExpiresIn(expiresIn);
            tbAuthSetting.setRefreshToken(refreshToken);
            tbAuthSetting.setTaobaoUserId(taobaoUserId);
            tbAuthSetting.setTaobaoUserNick(taobaoUserNick);
            tbAuthSetting.setTokenType(tokenType);
            systemSettingService.saveSetting(tbAuthSetting, 0);
            systemSettingService.activeSetting(TaobaoAuthSetting.class, 0);
            return "close";
        } else if (state.startsWith(TopAuthConstants.STATE_USER)) {
            String[] tmp = state.split(":");
            String key = CacheKeys.TOP_USER_STATE + "-" + tmp[1];
            Long userId = Long.valueOf(redisTemplate.opsForValue().get(key));
            redisTemplate.delete(key);
            TaobaoAccountService.TaobaoAccountSaveParam taobaoAccount = new TaobaoAccountService.TaobaoAccountSaveParam();
            taobaoAccount.setAccessToken(accessToken);
            taobaoAccount.setRefreshToken(refreshToken);
            taobaoAccount.setTaobaoOpenId(taobaoOpenId);
            taobaoAccount.setTaobaoUserId(taobaoUserId);
            taobaoAccount.setTaobaoUserNick(taobaoUserNick);
            taobaoAccount.setExpiresIn(expiresIn);
            taobaoAccountService.saveUserTaobaoAccount(userId, taobaoAccount);
            userService.clearTaobaoRelationId(userId);
            userService.clearTaobaoSpecialId(userId);
            tbkPrivateService.generateUserSpecialId(userId);
            tbkPrivateService.generateUserRelationId(userId);
            map.put("authOk", true);
            return "topAuth";
        }
        return null;
    }

}
